/*** 
 * @_______________#########_______________________ 
 * @______________############_____________________ 
 * @______________#############____________________ 
 * @_____________##__###########___________________ 
 * @____________###__######_#####__________________ 
 * @____________###_#######___####_________________ 
 * @___________###__##########_####________________ 
 * @__________####__###########_####_______________ 
 * @________#####___###########__#####_____________ 
 * @_______######___###_########___#####___________ 
 * @_______#####___###___########___######_________ 
 * @______######___###__###########___######_______ 
 * @_____######___####_##############__######______ 
 * @____#######__#####################_#######_____ 
 * @____#######__##############################____ 
 * @___#######__######_#################_#######___ 
 * @___#######__######_######_#########___######___ 
 * @___#######____##__######___######_____######___ 
 * @___#######________######____#####_____#####____ 
 * @____######________#####_____#####_____####_____ 
 * @_____#####________####______#####_____###______ 
 * @______#####______;###________###______#________ 
 * @________##_______####________####______________ 
 * @
 * @Author: ipk518 18163976442@163.com
 * @Date: 2024-06-19 10:31:14
 * @LastEditors: ipk518 121206530@qq.com
 * @LastEditTime: 2025-05-19 11:06:25
 * @FilePath: /etws-sxk2307/src/Devices/Lmx2820.cpp
 * @Description: 
 * @************佛祖保佑************
 * @Copyright (c) 2024 by etws@quyujiang, All Rights Reserved. 
 */

#include "Lmx2820.h"
#include "lmx2820Registers.h"
#include "commHeader.h"
#include "Spi.h"

static int lmx2820Fd = -1;

const int m_onlyRead[16]  = { 71,72,73,74,75,76,113,114,115,116,117,118,119,120,121,122};

// #define _LMX2820_DEBUG_

bool lmx2820Open(const char* filename)
{
    lmx2820Fd = spiInit(filename);
    if(lmx2820Fd < 0){
        qlog_e("Open lmx2820 failed!");
		return false;
    }
	return true;
}

void lmx2820Close(void)
{
    close(lmx2820Fd);
}

/*** 
 * @description: 监测锁定
 * @return 
 * 0=unlock
 * 1=unlock
 * 2=lock
 * 3=invalid
 */
int lmx2820GetLock(void)
{
    int m_lockStatus = 0;
    uint8_t wbuf[3] = {0};
    uint8_t rbuf[3] = {0};
    uint16_t regValue = 0;
    wbuf[0] = (0x4a | 0x80);
    spiTransmit(lmx2820Fd,wbuf,1,rbuf,2);
    regValue = (uint16_t)(rbuf[0] << 8) | (rbuf[1]);
    // qlog_i("lmx2820 lock:%#x.",regValue);
    m_lockStatus = ((regValue & 0xc000) >> 14);
    return m_lockStatus;
}

uint16_t lmx2820WrRd(uint32_t address) 
{
    int wlen = 3,rlen = 1;
    uint8_t wbuf[3] = {0};
    uint8_t rbuf[3] = {0};
    wbuf[0] = (uint8_t)(address >> 16);
    wbuf[1] = (uint8_t)(address >> 8);
    wbuf[2] = (uint8_t)(address);
    
    if(wbuf[0] >= 0x80) {
        wlen=1;
        rlen=2;
    } else {
        wlen=3;
        rlen=0;
    }
    spiTransmit(lmx2820Fd,wbuf,wlen,rbuf,rlen);//每次写入3个字节
    return ((uint16_t)(rbuf[0] << 8) | rbuf[1]);
}

bool lmx2820Config(void)
{
    bool ret = true;
    int j = 0;
    uint8_t wbuf[3] = {0};
    uint8_t rbuf[3] = {0};
    uint8_t regAddr = 0;
    uint16_t regWrite = 0;
    uint16_t regRead = 0;
    for(int i = 0;i < LMX2820_NUM_REGS;i++)
    {
        regAddr = (uint8_t)(lmx2820_revd_registers[i] >> 16);
        regWrite = (uint16_t)lmx2820_revd_registers[i];

        wbuf[0] = (uint8_t)(lmx2820_revd_registers[i] >> 16);
        wbuf[1] = (uint8_t)(lmx2820_revd_registers[i] >> 8);
        wbuf[2] = (uint8_t)(lmx2820_revd_registers[i]);
        spiTransmit(lmx2820Fd,wbuf,3,NULL,0);//每次写入3个字节
        wbuf[0] |= 0x80;
        spiTransmit(lmx2820Fd,wbuf,1,rbuf,2);//写一个地址读2个寄存器
        regRead = (uint16_t)(rbuf[0] << 8 | rbuf[1]);
#ifdef _LMX2820_DEBUG_
        qlog_i("lmx2820:%x",lmx2820_revd_registers[i]);
        qlog_i("lmx2820:reg = %x:write = 0x%x",regAddr,regWrite);
        qlog_i("lmx2820:reg = %x:read = 0x%x\n",regAddr,regRead);
#endif
        if(regWrite != regRead) {
            int flag = 0;
            for(j = 0; j<16; j++) {
                if(regAddr == m_onlyRead[j]) {
                    break;
                }
                flag++;
            } 
            if(flag == 15) {
                ret = false;
                qlog_e("lmx2820:%d:write = 0x%08x\n",regAddr,regWrite);
                qlog_e("lmx2820: %d:read = 0x%08x\n",regAddr,regRead);
            }
        }
        usleep(1000);
    }
    return ret;
}

//R0:bit0 power down
//R1:bit1 reset
bool lmx2820Reset(void)
{
    bool ret = false;
    uint32_t reset = 0x2;
    uint8_t wbuf[3] = {0};
    uint8_t rbuf[3] = {0};
    wbuf[0] = 0;
    wbuf[1] = (uint8_t)(reset >> 8);
    wbuf[2] = (uint8_t)(reset);
    spiTransmit(lmx2820Fd,wbuf,3,NULL,0);//每次写入3个字节
    
    usleep(10000);//10ms
    wbuf[0] |= 0x80;
    spiTransmit(lmx2820Fd,wbuf,1,rbuf,2);
    qlog_i("LMX2820 0x00寄存器:%#x.",((uint16_t)(rbuf[0] << 8) | rbuf[1]));
    if((rbuf[1]&0x2) == reset) {
        qlog_e("lmx2820 reset failed.");
        ret = false;
    } else {
        qlog_i("lmx2820 reset sucess.");
        ret = true;
    }
    return ret;
}